package com.surge;

import java.util.List;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.boot.MetadataSources;
import org.hibernate.boot.registry.StandardServiceRegistry;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

public class SurgeTest {
	
	private SessionFactory sessionFactory;
	// 生产环境不允许 把session与transaction 设置成成员变量，因为涉及到并发问题
	private Session session;
	private Transaction transaction;
	
	// junit 方法init 与 destory。 这样只需要test中写主要的业务测试逻辑
	@Before
	public void init(){
		//1、 版本5.x	
		final StandardServiceRegistry registry = new StandardServiceRegistryBuilder()
				.configure() // configures settings from hibernate.cfg.xml
				.build();
		try {
			sessionFactory = new MetadataSources( registry ).buildMetadata().buildSessionFactory();
		}
		catch (Exception e) {
			System.out.println(e);
			StandardServiceRegistryBuilder.destroy( registry );
		}
		// 2. 创建一个 Session 对象
		session = sessionFactory.openSession();

		// 3. 开启事务
		transaction = session.beginTransaction();
	}
	@After
	public void destory(){
		// 5. 提交事务
		transaction.commit();

		// 6. 关闭 Session
		session.close();

		// 7. 关闭 SessionFactory 对象
		sessionFactory.close();
	}
	
	/*
	 * ============================    测试逻辑代码    ============================
	 */
	
	/*
	 * 继承映射 使用joinedsubclass
	 */
	
	/**
	 * 插入操作: 
	 *  生成了两张表，多了student表，用来存与person不同的值
	 */
	@Test
	public void testSave(){
		
		Person person = new Person();
		person.setAge(11);
		person.setName("AA");
		
		session.save(person);
		
		Student stu = new Student();
		stu.setAge(22);
		stu.setName("BB");
		stu.setSchool("ATGUIGU");
		
		session.save(stu);
		
	}
	
	
	/**
	 * 缺点:
	 * 1. 使用了辨别者列.
	 * 2. 子类独有的字段不能添加非空约束.
	 * 3. 若继承层次较深, 则数据表的字段也会较多. 
	 */
	
	/**
	 * 优点:
	 * 1. 不需要使用了辨别者列.
	 * 2. 子类独有的字段能添加非空约束.
	 * 3. 没有冗余的字段. 
	 */
	
	/**
	 * 查询: 太费劲
	 * 1. 查询父类记录, 做一个左外连接查询
	 * 2. 对于子类记录, 做一个内连接查询. 
	 */
	@SuppressWarnings({ "unchecked", "deprecation" })
	@Test
	public void testQuery(){
		// 查询父类记录 
		List<Person> persons = session.createQuery("FROM Person").list();
		System.out.println(persons.size()); 
		
		// 查询子类记录 自动识别TYPE
		List<Student> stus = session.createQuery("FROM Student").list();
		System.out.println(stus.size()); 
	}
	
	
	
}
